#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 1000
#define TRUE 1
#define FALSE 0
#define NONVOID 0
#define OVERFLOW 1
#define NONDEFINE 2
#define INVALID 3
#define NOTFOUND 404
struct PersonName{
    char Name[1000]; 
    int Last;
};
struct PersonPhoneNum
{
    char PhoneNum[1000];
    int Last;
};
struct PersonalInfo{
    struct PersonName PName;
};
struct Contact{
    struct PersonPhoneNum PPhoNum;
};
/*
    头像
    struct PersonalInfo{
        *姓名
        姓名拼音
        struct Work{
            公司
            职位
        }
        称呼
        关系
        生日
        农历生日
    }
    struct Contact{
        *手机
        邮箱
        struct SocialAccount{
            QQ
            微信
            脸书
            推特
            Ins
            网站
        };
    };
*/
struct ContactPerson{
    struct PersonalInfo Pi;
    struct Contact Ct;
};
typedef struct LNode *PtrToLNode;
struct LNode{
    struct ContactPerson m_Person;
    PtrToLNode Next;
};
typedef PtrToLNode Person;
typedef PtrToLNode List;



// Initialize an empty linear list
List MakeEmpty();

// ElementType FindKth(int K, List L)
// Return encounterpart element according to order K
List FindKth(int K, List L);

// int Find(ElementType X, List L) exp
// Find the position where element X initially occurs in linear list L
List Find(int , List L);
List Find(char *, List L);
List Find(Person , List L);
List Find(struct PersonalInfo *, List L);
List Find(struct Contact *, List L);
List Find(struct PersonName *, List L);
List Find(struct PersonPhoneNum *, List L);

// void Insert(ElementType X, int i, List L)
// Insert a new element X before order i in linear list L 
List Insert(int X, int i, List L);

// Delete the very element on order i
List Delete(int i, List L);

// Return the length of linear list L which is n
int Length(List L);

List MakeEmpty(){
    List PtrL = (List) malloc (sizeof(List));
    PtrL->Next = NULL;
    return PtrL;
}

List FindKth(int K, Person PtrL){
    List p = PtrL;
    if(K < 1){
        printf("Operation Error!\nError Code %02x\n",INVALID);
        return NULL;
    }
    int i = 1 ;
    for(; K > i && p != NULL ; p = p->Next, i++);
    if(i == K){
        return p;
    }
    else{
        return NULL;
    }
}

int Find(char *str, Person PtrL){
    Person p = PtrL;
    char *s = str;
    int length = Length(PtrL);
    for(int j = 0 ; p->Next != NULL ; p = p->Next){
        int i;
        for(i = 0 ; i <= p->m_Person.Pi.PName.Last && s[i] == p->m_Person.Pi.PName.Name[i] ; i++);
        if(i == p->m_Person.Pi.PName.Last + 1)
            PtrL = p;
    }
    if(p->Next == NULL){
        printf("Operation Error!\nError Code %02x\n",NOTFOUND);
        return NULL;
    }
    else{
        return p;
    }
}

Person Insert(int X, int i, Person PtrL){
    Person p,s;
    if(i == 1){
        s = (Person) malloc(sizeof(struct LNode));
        s->num = X;
        s->Next = PtrL;
        return s;
    }
    p = FindKth(i - 1,PtrL);
    if(p == NULL){
        printf("Operation Error!\nError Code %02x\n",INVALID);
        return NULL;
    }
    else{
        s = (Person) malloc(sizeof(struct LNode));
        s->num = X;
        s->Next = p->Next;
        p->Next = s;
        return PtrL;
    }
}

Person Delete(int i, Person PtrL){
    Person p,s;
    if(i < 1){
        printf("Operation Error!\nError Code %02x\n",INVALID);
        return NULL;
    }
    if(i == 1){
        s = PtrL;
        if(PtrL != NULL)
            PtrL = PtrL->Next;
        else 
            return NULL;
        free(s);
        return PtrL;
    }
    p = FindKth(i-1,PtrL);
    if(p == NULL){
        printf("Operation Error!\nError Code 1%02x\n",INVALID);
        return NULL;
    }
    else if(p->Next == NULL){
        printf("Operation Error!\nError Code 2%02x\n",INVALID);
        return NULL;;
    }
    else{
        s = p->Next;
        p->Next = s->Next;
        free(s);
        return PtrL;
    }
}

int Length(Person PtrL){
    Person p = PtrL;
    int i = 0;
    if(PtrL == NULL){
        return i;
    }
    for(; p != NULL ; i++, p = p->Next);
    return i;
}

// void ShowList(List L){
//     List PtrL = L;
//     for(int i = 1 ; PtrL->Next != NULL ; i++){
//         printf("%dL = %d\n",i,PtrL->num);
//         PtrL = PtrL->Next;
//     }
// }